#include "esp01s.h"
#include "esp01s_hw_uart.h"
//freertos
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
//t_at_t 对象
t_at_t *ESP01S=NULL;
//esp配置
esp_cfg_t esp_cfg;

rbuf esp_ringbuf;
//freeRTOS 事件组(用于等待AT对象初始化完成)-----阻塞
static EventGroupHandle_t esp_osEvent = NULL;
uint8_t esp_Opean_callback(void *Ptx, uint8_t *dataBuf, uint8_t data_len, uint8_t *cmd_Urc_String) {

    printf("esp_opean_callback handle OK  . %s\n", cmd_Urc_String);
    return 0;
}
uint8_t esp_send_callback(void *Ptx, uint8_t *dataBuf, uint8_t data_len, uint8_t *cmd_Urc_String) {
    
    printf("esp_send_callback handle OK  . %s\n", cmd_Urc_String);
    return 0;
}

// 硬件接口(实际的发送函数)
uint8_t esp_send_cmd(void *Ptx, uint8_t *dataBuf, uint32_t bufLen) {

    HAL_UART_Transmit(&esp_huart4, bbb, bufLen, 1000);
    return 0;
}

/**
 * @brief  发送AT命令到esp模块并等待响应
 * @param CMD 要发送的AT命令字符串
 * @param Data_len 要发送的AT命令长度
 * @param CMD_UCR 预期的响应字符串
 * @param Phandle 响应处理函数的回调函数
 * @param waittime 等待响应的时间（单位：毫秒）
 * @param resendCount 重试发送的次数
 * @return esp_error_t 返回发送结果的状态
 * @note: 该函数会阻塞等待响应，直到超时或收到预期的响应并且封装了
 * t_at_t 对象  t_at_t *ESP01S=NULL;
 */
esp_error_t esp_send_cmd(char *CMD,                  //
                            uint8_t Data_len,          //
                            char *CMD_UCR,             //
                            t_at_urc_callback Phandle, //
                            uint32_t waittime,         //
                            uint8_t resendCount        //
                        )
                             {
    T_ErrType ret;
    ret = t_at_cmd_send(ESP01S, Data_len, CMD, CMD_UCR, Phandle, waittime, resendCount);
    if (ret == AT_OK) {
        return esp_send_ok;
    } else {
        return esp_send_fail;
    }
}

/**
 * @brief  ESP模块的电源控制函数
*/
void esp_power_gpio_set(void) {
    // GPIO_InitTypeDef GPIO_InitStruct = {0};

    // /* GPIO Ports Clock Enable */
    // __HAL_RCC_GPIOD_CLK_ENABLE();
    // HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_SET);
    // /*Configure GPIO pin : PD15 */
    // GPIO_InitStruct.Pin = GPIO_PIN_15;
    // GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    // GPIO_InitStruct.Pull = GPIO_PULLUP;
    // GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    // HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
    // // 开机管脚动作
    // HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_RESET);
    // vTaskDelay(2000);
    // HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_SET);
    // vTaskDelay(1000);  // 10s开机
}

esp_error_t esp_power_open(void)  // 开机
{
    char temp[20];
    esp_error_t ret;
    esp_power_gpio_set();
    snprintf(temp, sizeof(temp), "AT\r\n");
    int len = strlen(temp);
    ret = esp_send_cmd(temp, len, "OK", esp_Opean_callback, 1000, 2);
    return ret;
}
// 开机esp模块
esp_error_t esp_do_ml307_powr_open_ok(uint8_t do_work_re) {
    ml307_error_t ret;
    uint8_t retry_count = 0;
    do {
        ret = esp_power_open();
        if (ret == esp_send_fail) {
            retry_count++;
        } else {
            break;
        }
    } while (retry_count < do_work_re);

    if (retry_count == do_work_re) {
        return esp_powr_open_fail;  // 开机失败
    }

    return esp_powr_open_ok;
}



uint8_t get_esp_mqttc_number(void){
    return esp_cfg.esp_mqttc_num;
}

extern void set_esp_mqtt_setup(uint8_t setup){
    esp_cfg.ml307_mqttc_num=setup;    
}

esp_error_t esp_creat(esp_cfg_t *esp_cfg_t) {
	
	  set_esp_mqtt_setup(1);//你需要创建多少个MQTTC(max 6)
    if (esp_cfg_t == NULL) {
        return esp_error;
    }
    // 动态申请内存
    char *tmp_cmd = AT_MALLOC(1024);
    EventGroupHandle_t *esp_osEvent = AT_MALLOC(sizeof(EventGroupHandle_t));
    if (!tmp_cmd  || !esp_osEvent) {
        AT_FREE(tmp_cmd);
        AT_FREE(esp_osEvent);
        return esp_error;
    }

    // 初始化AT对象
    ESP01S = t_at_create(esp_send_cmd, esp_send_callback, 100, 1);
    if (ESP01S == NULL) {
        AT_FREE(tmp_cmd);
        AT_FREE(esp_osEvent);
        return esp_error;
    }

    // 创建OS锁和循环队列
    t_at_os_create(ESP01S, esp_osEvent, t_at_os_init_t, t_at_os_lock_t, t_at_os_unlock_t);
    t_at_ringbuffer_create(ESP01S, 
                           &esp_ringbuf, 
                           rbuf_init, 
                           rbuf_push, 
                           rbuf_pop, 
                           rbuf_clear, 
                           rbuf_is_empty,
                           rbuf_is_full
                           );

    // 开机模块并检查状态
    esp_error_t ret = esp_do_ml307_powr_open_ok(1);
    if (ret == esp_send_fail) {
        esp_cfg_t->esp_status = esp_power_down;
        AT_FREE(tmp_cmd);
        AT_FREE(esp_osEvent);
        return esp_powr_open_ok;  // 开机失败
    }
    uint16_t len = 0;
    // 发送AT指令	
    AT_CMD_FORMAT_AUTO_CRLF(tmp_cmd,1024,&len,"AT");
	printf("cmd:%s\r\n",tmp_cmd);
    ret = esp_send_cmd(tmp_cmd, len, "OK", esp_send_callback, 1000, 2);
    
    // 释放临时缓冲区
    AT_FREE(tmp_cmd);
    return ret;
}


//套接上传数据
/**
 * @brief 发送数据到指定的MQTT主题
 * @param mqttc_num MQTT客户端编号
 * @param topic 要发送数据的主题
 * @param data 要发送的数据 
 * @param data_len 数据长度 数据最大长度256
 * @return ml307_error_t 发送结果
 * @note 确保MQTT客户端已连接，且主题和数据格式正确。
 */
ml307_error_t esp_send_net_data(uint8_t mqttc_num,char *topic,char *data,uint16_t data_len){
	
}